﻿using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Threading;
using Liekhus.Testing.BDD.Core;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TechTalk.SpecFlow;
using SpecFlowAlias = TechTalk.SpecFlow;
using System;

namespace Liekhus.Testing.BDD.DevExpress
{
    //[Binding]
    public class StepDefinition : BaseStepDefinitions
    {
        private const string FUNCTIONAL_FILENAME = "FunctionalTests.ets";

        private string WorkingFolder
        {
            get
            {
                return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            }
        }

        private string TestFilePath
        {
            get
            {
                return Path.Combine(WorkingFolder, FUNCTIONAL_FILENAME);
            }
        }

        private void WriteFileCommand(string command)
        {
            string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            Stream stream = new FileStream(TestFilePath, FileMode.Append, FileAccess.Write);
            TextWriter writer = new StreamWriter(stream);
            writer.WriteLine(command);
            writer.Close();
        }

        [Given(@"I am starting a new test")]
        public void GivenIAmStartingANewTest()
        {
            if (File.Exists(TestFilePath)) { File.Delete(TestFilePath); }
        }

        [Given(@"the testing environment is reset")]
        public void GivenTheTestingEnvironmentIsReset()
        {
            WriteFileCommand("#IncludeFile EnvironmentSetup.inc");
        }

        [Given(@"the application is open")]
        public void WhenTheApplicationIsOpen()
        {
            string applicationName = ConfigurationManager.AppSettings["ApplicationName"];
            WriteFileCommand(string.Format("#Application {0}", applicationName));
        }

        [When("I open the record matching \"(.*)\" = \"(.*)\"")]
        public void WhenIOpenTheRecordMatching(string fieldName, string value)
        {
            WriteFileCommand("*ProcessRecord");
            WriteFileCommand(string.Format(" {0} = {1}", fieldName, value));
        }

        public override void GivenIAmLoggedInAs(string username)
        {
            WriteFileCommand("*FillForm");
            try
            {
                WriteFileCommand(string.Format(" User Name = {0}", ConfigurationManager.AppSettings[string.Format("Login.{0}.Username", username)]));
                WriteFileCommand(string.Format(" Password = {0}", ConfigurationManager.AppSettings[string.Format("Login.{0}.Password", username)]));
            }
            catch
            {
                Assert.Fail(string.Format("Security settings for {0} have not been configured.", username));
            }
            WriteFileCommand("*Action Log On");
        }

        //[Given("I am at the \"(.*)\" screen")]
        public override void WhenIAmAtTheScreen(string page)
        {
            WriteFileCommand(string.Format("*Action Navigation({0})", page));
        }

        //[When("I click the \"(.*)\" link")]
        public override void WhenIClickTheLink(string text)
        {
            //var link = WebBrowser.Current.Link(Find.ByText(text));

            //if (link.Exists == false)
            //{
            //    Assert.Fail(string.Format("Could not find {0} link on the page.", text));
            //}
            //link.Click();
        }

        //[When("I click the \"(.*)\" button")]
        public override void WhenIClickTheButton(string text)
        {
            WriteFileCommand(string.Format("*Action {0}", text));
        }

        //[When("I enter the following information")]
        public override void WhenIEnterTheFollowingInformation(SpecFlowAlias.Table table)
        {

            WriteFileCommand("*FillForm");
            foreach (var row in table.Rows)
            {
                if (!string.IsNullOrEmpty(row["Value"].ToString()))
                {
                    WriteFileCommand(string.Format(" {0} = {1}", row["Field"], row["Value"]));
                }
            }
        }

        //[Then("I should see the following results")]
        public override void ThenIShouldSeeTheFollowingResults(SpecFlowAlias.Table table)
        {
            WriteFileCommand("*CheckFieldValues");
            foreach (var row in table.Rows)
            {
                if (!string.IsNullOrEmpty(row["Value"].ToString()))
                {
                    WriteFileCommand(string.Format(" {0} = {1}", row["Field"], row["Value"]));
                }
            }
        }

        //[Then("I should see the following on the screen")]
        public override void ThenIShouldSeeTheFollowingOnScreen(SpecFlowAlias.Table table)
        {
            //foreach (var row in table.Rows)
            //{
            //    var value = row["Value"];
            //    Assert.IsTrue(WebBrowser.Current.ContainsText(value), string.Format("Could not find text '{0}' on the page.", value));
            //}
        }

        [When("I verify results")]
        public void WhenIVerifyResults()
        {
            string testRunner = ConfigurationManager.AppSettings["TestRunner"];
            string filePath = Path.Combine(WorkingFolder, "TestsLog.xml");
            if (File.Exists(filePath)) { File.Delete(filePath); }

            ProcessStartInfo info = new ProcessStartInfo(Path.Combine(WorkingFolder, testRunner), string.Format("{0}", TestFilePath));
            Process.Start(info);

            while (!File.Exists(filePath))
            {
            }

            DataSet xml = new DataSet();
            Thread.Sleep(5000);
            xml.ReadXml(filePath, XmlReadMode.InferSchema);

            bool hasPassed = true;
            DataTable tests = xml.Tables["Test"];
            foreach (DataRow row in tests.Rows)
            {
                if (!row["Result"].ToString().Equals("Passed"))
                {
                    hasPassed = false;
                    break;
                }
            }

            xml = null;
            if (!hasPassed)
            {
                File.Copy(filePath, Path.Combine(WorkingFolder, string.Format("TestsLog_{0}.xml", DateTime.Now.ToString("yyMMdd_hhmm"))));
            }
            File.Delete(filePath);

            Assert.IsTrue(hasPassed == true);
        }

    }
}
